package com.fingard.dsp.bank.directbank.chinapay05;

import com.chinapay.secss.SecssConstants;
import com.chinapay.secss.SecssUtil;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IContract;
import com.fingard.dsp.bank.directbank.chinapay01.util.SDKUtil;
import com.fingard.dsp.bank.reqrespobj.contract.*;
import com.fingard.dsp.bank.reqrespobj.contract.detail.RetAtsContractDetail;
import com.fingard.text.StringHelper;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;

import java.util.*;

/**
 * 上海银联短信签约
 * 
 * @author Cruise
 * @date 2019/5/21
 */
public class ChinaPay05Contract extends ChinaPay05Base implements IContract {
	@Override
	public RetAtsContract contract(ReqContract p_req) throws Exception {
		RetAtsContract retAts = new RetAtsContract(p_req.reqHeader);
		RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
		tmpRetDetail.reqSeqID = p_req.contractDetail.askNumber;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req.contractDetail.recAct, "contract");
			if (actItem != null) {
				Map<String, String> tmpContractRequest = new HashMap<String, String>();
				
				tmpContractRequest.put("Version", "20150922");
				tmpContractRequest.put("AccessType", "0");
				tmpContractRequest.put("InstuId", "");
				tmpContractRequest.put("AcqCode", "");
				tmpContractRequest.put("MerId", actItem.merchantId);
				tmpContractRequest.put("MerOrderNo", p_req.contractDetail.askNumber);
				tmpContractRequest.put("TranDate", Format.Date8Format.format(new Date()));
				tmpContractRequest.put("TranTime", Format.Time6Format.format(new Date()));
				tmpContractRequest.put("BusiType", "0001");
				tmpContractRequest.put("RiskData", "");
				tmpContractRequest.put("BankInstNo", "");
				tmpContractRequest.put("Signature", "");
				if ("01".equals(p_req.contractDetail.step)) {
					tmpContractRequest.put("TranType", "0608");
					tmpContractRequest.put("RemoteAddr", "");
					
					JSONObject cardTranData = new JSONObject();
					cardTranData.put("CardNo", p_req.contractDetail.payAct);
					String cardType = "";
					if ("1".equals(p_req.contractDetail.cardType)) {
						cardType = "06";
					} else if ("3".equals(p_req.contractDetail.cardType)) {
						cardType = "02";
					} else {
						cardType = "01";
					}
					cardTranData.put("AccType", cardType);
					cardTranData.put("AccName", p_req.contractDetail.payName);
					cardTranData.put("CertType", convertCertTypeToBank(p_req.contractDetail.certType));
					cardTranData.put("CertNo", p_req.contractDetail.certNum);
					cardTranData.put("MobileNo", p_req.contractDetail.cellPhone);
					
					String strCardTranData = cardTranData.toString();
					 WriteBankLogLn("加密前的卡保留域:" + strCardTranData);
				     strCardTranData = Base64.encodeBase64String(strCardTranData.getBytes(getCharset()));
				     SecssUtil secssUtil = getSecssUtil(actItem);
				     secssUtil.encryptData(strCardTranData);
				     if (SecssConstants.SUCCESS.equals(secssUtil.getErrCode())) {
				         strCardTranData = secssUtil.getEncValue();
				     } else {
				    	 tmpRetDetail.respCode = "-1";
						 tmpRetDetail.respInfo = secssUtil.getErrCode() + "+" + secssUtil.getErrMsg();
						 retAts.writeRetDetail(tmpRetDetail);
						 return retAts;
				     }
					tmpContractRequest.put("CardTranData", strCardTranData);
				} else if ("02".equals(p_req.contractDetail.step)) {
					tmpContractRequest.put("TranType", "9904");
					tmpContractRequest.put("MerPageUrl", "");
					tmpContractRequest.put("MerBgUrl", actItem.notifyURL);
					tmpContractRequest.put("RemoteAddr", "");
					
					JSONObject cardTranData = new JSONObject();
					cardTranData.put("CardNo", p_req.contractDetail.payAct);
					String cardType = "";
					if ("1".equals(p_req.contractDetail.cardType)) {
						cardType = "06";
					} else if ("3".equals(p_req.contractDetail.cardType)) {
						cardType = "02";
					} else {
						cardType = "01";
					}
					cardTranData.put("AccType", cardType);
					cardTranData.put("AccName", p_req.contractDetail.payName);
					cardTranData.put("CertType", convertCertTypeToBank(p_req.contractDetail.certType));
					cardTranData.put("CertNo", p_req.contractDetail.certNum);
					cardTranData.put("MobileNo", p_req.contractDetail.cellPhone);
					cardTranData.put("MobileAuthCode", p_req.contractDetail.smsCode);
					String strCardTranData = cardTranData.toString();
					 WriteBankLogLn("加密前的卡保留域:" + strCardTranData);
				     strCardTranData = Base64.encodeBase64String(strCardTranData.getBytes(getCharset()));
				     SecssUtil secssUtil = getSecssUtil(actItem);
				     secssUtil.encryptData(strCardTranData);
				     if (SecssConstants.SUCCESS.equals(secssUtil.getErrCode())) {
				         strCardTranData = secssUtil.getEncValue();
				     } else {
				    	 tmpRetDetail.respCode = "-1";
						 tmpRetDetail.respInfo = secssUtil.getErrCode() + "+" + secssUtil.getErrMsg();
						 retAts.writeRetDetail(tmpRetDetail);
						 return retAts;
				     }
					tmpContractRequest.put("CardTranData", strCardTranData);
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = "未能识别的step：" + p_req.contractDetail.step;
					retAts.writeRetDetail(tmpRetDetail);
					return retAts;
				}
				SecssUtil secssUtil = getSecssUtil(actItem);
				Map<String, String> sendMap = new TreeMap<String, String>();
				Iterator<String> iterator = tmpContractRequest.keySet().iterator();
				while(iterator.hasNext()) {
					String key = iterator.next();
					String value = tmpContractRequest.get(key);
					
					if (key.startsWith("__")) {
	                    continue;
	                }
	                // 过滤空字段
	                if (StringHelper.isNullOrEmpty(value)) {
	                    continue;
	                }
	                sendMap.put(key, value);
				}
				WriteBankLogLn2("签约提交请求数据:\r\n" + SDKUtil.coverMap2String(sendMap));
				secssUtil.sign(sendMap);
				if (SecssConstants.SUCCESS.equals(secssUtil.getErrCode())) {
					sendMap.put("Signature", secssUtil.getSign());
					
					Map<String, String> tmpMapRet = sendDataToBank(sendMap, bankFront.getUrl("unionContract"));
					if (tmpMapRet.size() > 0) {
						tmpRetDetail.respCode = "0";
						tmpRetDetail.respInfo = tmpMapRet.get("respMsg");
						
						String tmpRespCode = tmpMapRet.get("respCode");
						if("01".equals(p_req.contractDetail.step)) {
							if (!"0000".equals(tmpRespCode)) {
								tmpRetDetail.respCode = "-1";
								tmpRetDetail.respInfo = tmpMapRet.get("respMsg");
							}
							tmpRetDetail.signConfirmType = this.getBankConfig().getMapValueByKey("signConfirmMapping",p_req.contractDetail.payBankCode);
						} else {
							//00 未签约	01 签约成功	02 签约失败	03 已撤销
							String signStatus = tmpMapRet.get("SignState");
							if ("01".equals(signStatus)) {
								tmpRetDetail.signState = ContractState.SUCCESS;
							} else if ("00".equals(signStatus)) {
								tmpRetDetail.signState = ContractState.UNSIGNED;
							} else {
								tmpRetDetail.signState = ContractState.FAIL;
							}
						}
						tmpRetDetail.unifiedCode = getBankConfig().getMapValueByKey("contractMapping", tmpRespCode);
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = "银行响应数据为空!";
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = "签名失败" + secssUtil.getErrMsg();
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未找到账号[" + p_req.contractDetail.recAct + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

    @Override
    public RetAtsContract upContract(ReqContract p_req) throws Exception {
        return null;
    }

    @Override
	public RetAtsContract qryContract(ReqContract p_reqQry) throws Exception {
		RetAtsContract retAts = new RetAtsContract(p_reqQry.reqHeader);
		RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
		tmpRetDetail.reqSeqID = p_reqQry.contractDetail.askNumber;
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqQry.contractDetail.recAct, "contract");
			if (actItem != null) {
				Map<String, String> tmpQryContractRequest = new HashMap<String, String>();

				tmpQryContractRequest.put("Version", "20150922");
				tmpQryContractRequest.put("AccessType", "0");
				tmpQryContractRequest.put("InstuId", "");
				tmpQryContractRequest.put("AcqCode", "");
				tmpQryContractRequest.put("MerId", actItem.merchantId);
				tmpQryContractRequest.put("BusiType", "0001");
				tmpQryContractRequest.put("TranType", "0504");
				tmpQryContractRequest.put("OriTranType", "9904");
				
				JSONObject cardTranData = new JSONObject();
				cardTranData.put("CardNo", p_reqQry.contractDetail.payAct);
				String strCardTranData = cardTranData.toString();
				 WriteBankLogLn("加密前的卡保留域:" + strCardTranData);
			     strCardTranData = Base64.encodeBase64String(strCardTranData.getBytes(getCharset()));
			     SecssUtil secssUtil = getSecssUtil(actItem);
			     secssUtil.encryptData(strCardTranData);
			     if (SecssConstants.SUCCESS.equals(secssUtil.getErrCode())) {
			         strCardTranData = secssUtil.getEncValue();
			     } else {
			    	 tmpRetDetail.respCode = "-1";
					 tmpRetDetail.respInfo = secssUtil.getErrCode() + "+" + secssUtil.getErrMsg();
					 retAts.writeRetDetail(tmpRetDetail);
					 return retAts;
			     }
				tmpQryContractRequest.put("CardTranData", strCardTranData);
				tmpQryContractRequest.put("Signature", "");
				
				Map<String, String> sendMap = new TreeMap<String, String>();
				Iterator<String> iterator = tmpQryContractRequest.keySet().iterator();
				while(iterator.hasNext()) {
					String key = iterator.next();
					String value = tmpQryContractRequest.get(key);
					
					if (key.startsWith("__")) {
	                    continue;
	                }
	                // 过滤空字段
	                if (StringHelper.isNullOrEmpty(value)) {
	                    continue;
	                }
	                sendMap.put(key, value);
				}
				WriteBankLogLn2("签约查询请求数据:\r\n" + SDKUtil.coverMap2String(sendMap));
				secssUtil.sign(sendMap);
				if (SecssConstants.SUCCESS.equals(secssUtil.getErrCode())) {
					sendMap.put("Signature", secssUtil.getSign());
					Map<String, String> tmpMapRet = sendDataToBank(sendMap, bankFront.getUrl("unionContract"));
					if (tmpMapRet.size() > 0) {
						tmpRetDetail.respCode = "0";
						tmpRetDetail.respInfo = tmpMapRet.get("respMsg");
						
						// 00 未签约 01 签约成功
						String signStatus = tmpMapRet.get("SignState");
						if ("01".equals(signStatus)) {
							tmpRetDetail.signState = ContractState.SUCCESS;
						} else {
							tmpRetDetail.signState = ContractState.UNSIGNED;
						}
						tmpRetDetail.signConfirmType = this.getBankConfig().getMapValueByKey("signConfirmMapping",p_reqQry.contractDetail.payBankCode);
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = "银行响应数据为空!";
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = "签名失败:" + secssUtil.getErrMsg();
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未找到账号:[" + p_reqQry.contractDetail.recAct + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

    @Override
    public RetAtsQryBatContract qryBatContract(ReqQryBatContract p_reqQry) throws Exception {
        return null;
    }
}
